/*
 * Copyright (c) 2025 Huawei Device Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License"),
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/**
 * @addtogroup TeeTrusted
 * @{
 *
 * @brief TEE（Trusted Excution Environment）可信执行环境API。
 *
 * 提供安全能力API，例如可信存储、加解密及可信时间等，用于可信应用程序开发。
 *
 * @since 20
 */

/**
 * @file tee_trusted_storage_api.h
 *
 * @brief 提供可信存储API。
 *
 * @library NA
 * @kit TEEKit
 * @include <TEEKit/tee_trusted_storage_api.h>
 * @syscap SystemCapability.Tee.TeeClient
 * @since 20
 */

#ifndef __TEE_TRUSTED_STORAGE_API_H
#define __TEE_TRUSTED_STORAGE_API_H

#include "tee_defines.h"
#include "tee_object_api.h"

#ifdef __cplusplus
extern "C" {
#endif

/**
 * @brief 定义与对象关联的数据流的起始位置。
 * 用于TEE_SeekObjectData函数。
 *
 * @since 20
 */
enum __TEE_Whence {
    /** 将起始位置设置为数据流的开头。 */
    TEE_DATA_SEEK_SET = 0,
    /** 将起始位置设置为当前数据流位置。 */
    TEE_DATA_SEEK_CUR,
    /** 将起始位置设置为数据流的末尾。 */
    TEE_DATA_SEEK_END
};

/**
 * @brief 定义对象枚举句柄。
 *
 * @since 20
 */
struct __TEE_ObjectEnumHandle;

/**
 * @brief 定义数据流位置的类型。
 *
 * @since 20
 */
typedef uint32_t TEE_Whence;

/**
 * @brief 定义存储ID，用于标识应用程序使用的存储空间。
 *
 * @since 20
 */
enum Object_Storage_Constants {
    /** 为每个应用程序提供独立的私有存储空间。 */
    TEE_OBJECT_STORAGE_PRIVATE = 0x00000001,
    /** 为应用程序提供独立的个性化存储空间。 */
    TEE_OBJECT_STORAGE_PERSO   = 0x00000002,
    /** 用于安全闪存的存储空间。 */
    TEE_OBJECT_SEC_FLASH       = 0x80000000,
    /** 用于RPMB存储的存储空间。 */
    TEE_OBJECT_STORAGE_RPMB    = 0x80000001,
    /** 用于凭据加密的存储空间。 */
    TEE_OBJECT_STORAGE_CE      = 0x80000002,
    /** 用于防回滚的存储空间。 */
    TEE_OBJECT_STORAGE_ANTIROLLBACK = 0x80000003,
};

/**
 * @brief 定义系统资源约束，如数据流位置指示器的最大值。
 *
 * @since 20
 */
enum Miscellaneous_Constants {
    /** 数据流位置指示器的最大长度。 */
    TEE_DATA_MAX_POSITION = 0xFFFFFFFF,
    /** 对象ID的最大长度，最大可扩展至128字节。 */
    TEE_OBJECT_ID_MAX_LEN = 64,
};

/**
 * @brief 定义数据流中可容纳的最大字节数。
 *
 * @since 20
 */
enum TEE_DATA_Size {
    /** 数据流中可容纳的最大字节数。 */
    TEE_DATA_OBJECT_MAX_SIZE = 0xFFFFFFFF
};

/**
 * @brief 定义TEE_ObjectHandle的handleFlags。
 * 该标志用于决定与对象关联的数据流的访问权限。
 *
 * @since 20
 */
enum Data_Flag_Constants {
    /** 数据流可读。 */
    TEE_DATA_FLAG_ACCESS_READ = 0x00000001,
    /** 数据流可写或可截断。 */
    TEE_DATA_FLAG_ACCESS_WRITE = 0x00000002,
    /** 可删除或重命名数据流。 */
    TEE_DATA_FLAG_ACCESS_WRITE_META = 0x00000004,
    /** 可通过多个TEE_ObjectHandle并发读取。 */
    TEE_DATA_FLAG_SHARE_READ = 0x00000010,
    /** 可通过多个TEE_ObjectHandle并发写入。 */
    TEE_DATA_FLAG_SHARE_WRITE = 0x00000020,
    /** 保留字段。 */
    TEE_DATA_FLAG_CREATE = 0x00000200,
    /** 保护已有同名文件。如果同名文件已存在则返回错误，否则创建新数据文件。 */
    TEE_DATA_FLAG_EXCLUSIVE = 0x00000400,
    /** 保护已有同名文件。如果同名文件已存在则返回错误，否则创建新数据文件。 */
    TEE_DATA_FLAG_OVERWRITE = 0x00000400,
    /** 第25位为1表示通过GID派生TA根密钥。 */
    TEE_DATA_FLAG_GID = 0x02000000,
    /** 第26位为1表示通过HUK2派生TA根密钥。 */
    TEE_DATA_FLAG_HUK2 = 0x04000000,
    /**
     * 第27位为1表示一次性派生32字节的TA根密钥；
     * 为0表示分段派生多个密钥后组合生成最终密钥。
     */
    TEE_DATA_FLAG_DERIVE_32BYTES_KEY_ONCE =  0x08000000,
    /** 第28位为1使用AES256，加密；为0使用AES128。 */
    TEE_DATA_FLAG_AES256 =  0x10000000,
    /** 第29位为1时优先打开旧版本数据。 */
    TEE_DATA_FLAG_OPEN_AESC = 0x20000000,
    /** 第30位为1表示使用国密算法保护数据。 */
    TEE_DATA_FLAG_GM =  0x40000000,
};

/**
 * @brief 创建持久对象。
 *
 * 此函数会创建一个带有初始化的TEE_Attribute和数据流的持久对象。\n
 * 可以使用返回的句柄访问对象的TEE_Attribute和数据流。
 *
 * @param storageID 指定要使用的存储空间。该值由Object_Storage_Constants指定。
 * @param ojbectID 指向对象标识符（即要创建的对象的名称）的指针。
 * @param objectIDLen 指定对象标识符的长度（以字节为单位）。长度不能超过128字节。
 * @param flags 指定创建的对象的标志。该值可以是
 * 一个或多个Data_Flag_Constants或Handle_Flag_Constants的组合。
 * @param attributes 指向一个瞬态对象的TEE_ObjectHandle，从中获取TEE_Attribute。
 * 如果持久对象不包含属性，则该参数可以为TEE_HANDLE_NULL。
 * @param initialData 指向用于初始化数据流的初始数据的指针。
 * @param initialDataLen 指定初始数据的长度（以字节为单位）。
 * @param object 指向在函数成功执行后返回的TEE_ObjectHandle的指针。
 *
 * @return TEE_SUCCESS：操作成功。\n
 *         TEE_ERROR_ITEM_NOT_FOUND：指定的存储空间不存在。\n
 *         TEE_ERROR_ACCESS_CONFLICT：发生访问冲突。\n
 *         TEE_ERROR_OUT_OF_MEMORY：内存不足，无法完成操作。\n
 *         TEE_ERROR_STORAGE_NO_SPACE：存储空间不足，无法创建对象。
 * @since 20
 */
TEE_Result TEE_CreatePersistentObject(uint32_t storageID, const void *objectID, size_t objectIDLen, uint32_t flags,
                                      TEE_ObjectHandle attributes, const void *initialData, size_t initialDataLen,
                                      TEE_ObjectHandle *object);

/**
 * @brief 打开已存在的持久对象。
 *
 * 返回的句柄可用于访问对象的TEE_Attribute和数据流。
 *
 * @param storageID 指定要使用的存储空间。该值由Object_Storage_Constants指定。
 * @param ojbectID 指向对象标识符（即要打开的对象的名称）的指针。
 * @param objectIDLen 指定对象标识符的长度（以字节为单位）。长度不能超过128字节。
 * @param flags 指定打开对象的标志。该值可以是一个或多个Data_Flag_Constants或
 * Handle_Flag_Constants的组合。
 * @param object 指向在函数成功执行后返回的TEE_ObjectHandle的指针。
 *
 * @return TEE_SUCCESS：操作成功。\n
 *         TEE_ERROR_ITEM_NOT_FOUND：指定的存储空间不存在。\n
 *         TEE_ERROR_ACCESS_CONFLICT：发生访问冲突。\n
 *         TEE_ERROR_OUT_OF_MEMORY：内存不足，无法完成操作。\n
 * @since 20
 */
TEE_Result TEE_OpenPersistentObject(uint32_t storageID, const void *objectID, size_t objectIDLen, uint32_t flags,
                                    TEE_ObjectHandle *object);

/**
 * @brief 从与对象关联的数据流中读取数据到缓冲区。
 *
 * 对象的TEE_ObjectHandle必须以TEE_DATA_FLAG_ACCESS_READ权限打开。
 *
 * @param object 指向要读取的对象的TEE_ObjectHandle。
 * @param buffer 指向用于存储读取数据的缓冲区的指针。
 * @param size 指定要读取的字节数。
 * @param count 指向存储实际读取字节数的变量的指针。
 *
 * @return TEE_SUCCESS：操作成功。\n
 *         TEE_ERROR_OUT_OF_MEMORY：内存不足，无法完成操作。\n
 * @since 20
 */
TEE_Result TEE_ReadObjectData(TEE_ObjectHandle object, void *buffer, size_t size, uint32_t *count);

/**
 * @brief 将缓冲区中的字节写入与对象关联的数据流。
 *
 * 对象的TEE_ObjectHandle必须以TEE_DATA_FLAG_ACCESS_WRITE权限打开。
 *
 * @param object 指向要写入数据的对象的TEE_ObjectHandle。
 * @param buffer 指向存储要写入数据的缓冲区的指针。
 * @param size 指定要写入的字节数，不能超过4096字节。
 *
 * @return TEE_SUCCESS：操作成功。\n
 *         TEE_ERROR_OUT_OF_MEMORY：内存不足，无法完成操作。\n
 *         TEE_ERROR_STORAGE_NO_SPACE：存储空间不足，无法完成操作。
 * @since 20
 */
TEE_Result TEE_WriteObjectData(TEE_ObjectHandle object, const void *buffer, size_t size);

/**
 * @brief 更改数据流的大小。
 *
 * 如果指定的大小小于当前数据流大小，超出部分的字节将被删除。\n
 * 如果指定的大小大于当前数据流大小，则在数据流末尾填充0来扩展数据流。\n
 * 对象句柄必须以TEE_DATA_FLAG_ACCESS_WRITE权限打开。
 *
 * @param object 指向要更改数据流大小的对象的TEE_ObjectHandle。
 * @param size 指定数据流的新大小。不能超过4096字节。
 *
 * @return TEE_SUCCESS：操作成功。\n
 *         TEE_ERROR_STORAGE_NO_SPACE：存储空间不足，无法完成操作。
 * @since 20
 */
TEE_Result TEE_TruncateObjectData(TEE_ObjectHandle object, size_t size);

/**
 * @brief 设置TEE_ObjectHandle 指向的数据流的位置。
 *
 * @param object 指向目标对象的TEE_ObjectHandle。
 * @param offset 指定要移动数据位置的字节数，不能超过4096字节。
 * @param whence 指定数据流中计算新位置的起始位置。
 *
 * @return TEE_SUCCESS：操作成功。\n
 *         TEE_ERROR_OVERFLOW：由于该操作导致的位置指示器超出TEE_DATA_MAX_POSIT。
 * @since 20
 */
TEE_Result TEE_SeekObjectData(TEE_ObjectHandle object, int32_t offset, TEE_Whence whence);

/**
 * @brief 将已打开的TEE_ObjectHandle及其对应的安全属性文件同步到磁盘。
 *
 * @param object 指向目标对象的TEE_ObjectHandle。
 *
 * @return TEE_SUCCESS：操作成功。\n
 * @since 20
 */
TEE_Result TEE_SyncPersistentObject(TEE_ObjectHandle object);

/**
 * @brief 更改对象标识符。
 *
 *TEE_ObjectHandle 必须以TEE_DATA_FLAG_ACCESS_WRITE_META权限打开。
 *
 * @param object 指向目标对象的句柄。
 * @param newObjectID 指向新的对象标识符的指针。
 * @param newObjectIDLen 指定新对象标识符的长度。
 *
 * @return TEE_SUCCESS：操作成功。\n
 * @since 20
 */
TEE_Result TEE_RenamePersistentObject(TEE_ObjectHandle object, void *newObjectID, size_t newObjectIDLen);

/**
 * @brief 为未初始化的对象枚举器分配一个句柄。
 *
 * @param obj_enumerator 指向新创建的对象枚举器句柄的指针。
 *
 * @return TEE_SUCCESS：操作成功。\n
 *         TEE_ERROR_OUT_OF_MEMORY：内存不足，无法完成操作。\n
 * @since 20
 */
TEE_Result TEE_AllocatePersistentObjectEnumerator(TEE_ObjectEnumHandle *obj_enumerator);

/**
 * @brief 释放与对象枚举器句柄关联的所有资源。
 *
 * 调用此函数后，对象句柄将不再有效，且与对象枚举器句柄关联的所有资源将被回收。\n
 * TEE_FreePersistentObjectEnumerator与TEE_AllocatePersistentObjectEnumerator成对使用。
 *
 * @param obj_enumerator 要释放的TEE_ObjectEnumHandle。
 *
 * @since 20
 */
void TEE_FreePersistentObjectEnumerator(TEE_ObjectEnumHandle obj_enumerator);

/**
 * @brief 将对象枚举器句柄重置为其分配后的初始状态。
 *
 * @param obj_enumerator 要重置的对象枚举器的TEE_ObjectEnumHandle。
 *
 * @since 20
 */
void TEE_ResetPersistentObjectEnumerator(TEE_ObjectEnumHandle obj_enumerator);

/**
 * @brief 开始枚举指定可信存储中的所有对象。
 *
 * 可使用TEE_GetNextPersistentObject获取对象信息。
 *
 * @param obj_enumerator 指向对象枚举器的TEE_ObjectEnumHandle。
 * @param storage_id 指定要枚举对象的存储空间。该值由Object_Storage_Constants指定。\n
 * 当前仅支持TEE_STORAGE_PRIVATE。
 *
 * @return TEE_SUCCESS：操作成功。\n
 *         TEE_ITEM_NOT_FOUND：storage_id不是TEE_STORAGE_PRIVATE或指定的存储空间中没有对象。
 * @since 20
 */
TEE_Result TEE_StartPersistentObjectEnumerator(TEE_ObjectEnumHandle obj_enumerator, uint32_t storage_id);

/**
 * @brief 获取对象枚举器中的下一个对象。
 *
 * 获取的信息包括TEE_ObjectInfo、objectID和objectIDLen。
 *
 * @param obj_enumerator 指向对象枚举器的TEE_ObjectEnumHandle。
 * @param object_info 指向获取到的TEE_ObjectInfo的指针。
 * @param object_id 指向用于存储获取到的objectID的缓冲区的指针。
 * @param object_id_len 指向objectIDLen的指针。
 *
 * @return TEE_SUCCESS：操作成功。\n
 *         TEE_ITEM_NOT_FOUND：表示对象枚举器中没有元素或枚举器尚未初始化。
 * @since 20
 */
TEE_Result TEE_GetNextPersistentObject(TEE_ObjectEnumHandle obj_enumerator,
    TEE_ObjectInfo *object_info, void *object_id, size_t *object_id_len);

/**
 * @brief 关闭TEE_ObjectHandle并删除对象。
 *
 * 该对象必须是持久对象，且对象句柄必须以TEE_DATA_FLAG_ACCESS_WRITE_META权限打开。
 *
 * @param object 指向要关闭的对象句柄。
 *
 * @return TEE_SUCCESS：操作成功。\n
 *         TEE_ERROR_STORAGE_NOT_AVAILABLE：对象存储在当前无法访问的存储区域。
 * @since 20
 */
TEE_Result TEE_CloseAndDeletePersistentObject1(TEE_ObjectHandle object);

#ifdef __cplusplus
}
#endif

#endif
/** @} */